package com.pumpkin.widget;

import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.yhotbms.R;

public class TabScroller extends HorizontalScrollView {
    private int INVALID_POSITION = -1;
    private OnClickListenerTab mOnTabClickListener;
    private LinearLayout tabContainer;
    private int mCurScrollPosition = 0;
    private int mCacheWidth;
    private Paint mIndicatorPaint;
    private int mIndicatorHeight = 3;
    private int mIndicatorWidth = 0;
    private int mCurrentPosition;
    private int mSelectColor = 0xFF0ed41a;
    private int mDefaultColor = 0xFF484848;
    private float mDensity;
    private View oldSelect;
    private OnTabSelectListener mOnTabSelectListener;

    public interface OnTabSelectListener {
        void onTabSelect(int position);
    }

    public TabScroller(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.TabScroller);
        mDefaultColor = attributes.getColor(R.styleable.TabScroller_default_color, mDefaultColor);
        mSelectColor = attributes.getColor(R.styleable.TabScroller_select_color, mSelectColor);
        init(context);
    }

    public TabScroller(Context context, AttributeSet attrs) {
        // defStyle==0的时候没有显示滚动条 与方法 setHorizontalScrollBarEnabled(false)效果一样;
        this(context, attrs, 0);
    }

    public TabScroller(Context context) {
        this(context, null);
    }

    @Override
    public void addView(View child) {
        if (child instanceof TextView) {
            ((TextView) child).setTextColor(mDefaultColor);
        }
        if (tabContainer != null && getChildCount() > 0) {
            child.setOnClickListener(mOnTabClickListener);
            tabContainer.addView(child);
            return;
        }
        super.addView(child);
    }

    @Override
    public void addView(View child, int index) {
        if (child instanceof TextView) {
            ((TextView) child).setTextColor(mDefaultColor);
        }
        if (tabContainer != null && getChildCount() > 0) {
            child.setOnClickListener(mOnTabClickListener);
            tabContainer.addView(child, index);
            return;
        }
        super.addView(child, index);
    }

    @Override
    public void addView(View child, ViewGroup.LayoutParams params) {
        if (child instanceof TextView) {
            ((TextView) child).setTextColor(mDefaultColor);
        }
        if (tabContainer != null && getChildCount() > 0) {
            child.setOnClickListener(mOnTabClickListener);
            tabContainer.addView(child, params);
            return;
        }
        super.addView(child, params);
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        if (child instanceof TextView) {
            ((TextView) child).setTextColor(mDefaultColor);
        }
        if (tabContainer != null && getChildCount() > 0) {
            child.setOnClickListener(mOnTabClickListener);
            tabContainer.addView(child, index, params);
            return;
        }
        super.addView(child, index, params);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        final int height = getHeight();
        View currentTab = tabContainer.getChildAt(mCurScrollPosition);
        if (currentTab == null) {
            return;
        }
        if (oldSelect instanceof TextView) {
            ((TextView) oldSelect).setTextColor(mDefaultColor);
        }
        oldSelect = currentTab;
        if (currentTab instanceof TextView) {
            ((TextView) currentTab).setTextColor(mSelectColor);
        }
        int width = currentTab.getWidth();
        float lineLeft = currentTab.getLeft() + (width - mIndicatorWidth) / 2;
        float lineRight = lineLeft + mIndicatorWidth;
        RectF indicatorRec = new RectF((int) lineLeft, height - mIndicatorHeight, (int) lineRight, height);
        canvas.drawRoundRect(indicatorRec, 50, 50, mIndicatorPaint);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mCacheWidth = 0;
        int cacheMargin = 0;
        int childCount = getChildCount();
        int width = MeasureSpec.getSize(widthMeasureSpec);
        // Log.e("", "onMeasure width:" + width + "  childCount:" + childCount);
        if (childCount == 0) {
            addView(tabContainer, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
            childCount = getChildCount();
        }
        for (int i = 0; i < childCount; i++) {
            View childAt = getChildAt(i);
            int measuredWidth = childAt.getMeasuredWidth();
            if ((childAt instanceof LinearLayout) && childCount == 1) {
                if (tabContainer != childAt) {
                    tabContainer = (LinearLayout) childAt;
                }
                int count = ((ViewGroup) childAt).getChildCount();

                for (int j = 0; j < count; j++) {
                    View childAt2 = ((ViewGroup) childAt).getChildAt(j);
                    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) childAt2.getLayoutParams();
                    int measuredWidth2 = childAt2.getMeasuredWidth();// +
                    cacheMargin += params.leftMargin + params.rightMargin;
                    mCacheWidth += measuredWidth2;
                    // Log.e("", "cacheMargin:" + cacheMargin +
                    // " ---  mCacheWidth:" + mCacheWidth);
                }
                // 超出的部分等于当前的宽度减去
                int over = width - mCacheWidth - cacheMargin;
                for (int j = 0; j < count; j++) {
                    View child2 = ((ViewGroup) childAt).getChildAt(j);
                    // over<0&&over>mCacheWidth

                    if (over >= 0) {
                        int eachMargin = (over) / count;
                        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) child2.getLayoutParams();
                        params.leftMargin += eachMargin / 2;
                        params.rightMargin += eachMargin / 2;
                        child2.setLayoutParams(params);
                    } else if (over < 0 && width > mCacheWidth) {
                        int eachMargin = (width - mCacheWidth) / count;
                        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) child2.getLayoutParams();
                        params.leftMargin = eachMargin / 2;
                        params.rightMargin = eachMargin / 2;
                        child2.setLayoutParams(params);
                    } else {
                        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) child2.getLayoutParams();
                        params.width = LayoutParams.WRAP_CONTENT;
                        params.leftMargin = 0;
                        params.rightMargin = 0;
                        child2.setLayoutParams(params);
                    }
                }
            } else {
                mCacheWidth += measuredWidth;
                int over = width - mCacheWidth;
                if (over > 0) {
                    int eachWidth = width / childCount;
                    ViewGroup.LayoutParams params = childAt.getLayoutParams();
                    params.width = eachWidth;
                    childAt.setLayoutParams(params);
                } else {
                    ViewGroup.LayoutParams params = childAt.getLayoutParams();
                    params.width = LayoutParams.WRAP_CONTENT;
                    childAt.setLayoutParams(params);
                }
            }
            int childWidthMeasureSpec = getChildMeasureSpec(MeasureSpec.UNSPECIFIED, 0, LayoutParams.WRAP_CONTENT);
            childAt.measure(childWidthMeasureSpec, heightMeasureSpec);
        }

    }

    public void setOnTabSelectListener(OnTabSelectListener listener) {
        mOnTabSelectListener = listener;
    }

    public int getCurrentPosition() {
        return mCurrentPosition;
    }

    public int getTabCount() {
        if (tabContainer == null) {
            return 0;
        }
        return tabContainer.getChildCount();
    }

    protected void onTabSelect(int position) {
        if (mOnTabSelectListener != null) {
            mOnTabSelectListener.onTabSelect(position);
        }
    }

    private int getPositionForView(View view) {
        View listItem = view;
        try {
            View v;
            while (!(v = (View) listItem.getParent()).equals(tabContainer)) {
                listItem = v;
            }
        } catch (ClassCastException e) {
            return INVALID_POSITION;
        }
        final int childCount = tabContainer.getChildCount();
        for (int i = 0; i < childCount; i++) {
            if (tabContainer.getChildAt(i).equals(listItem)) {
                return i;
            }
        }

        return INVALID_POSITION;
    }

    private void addContainer(Context context) {
        if (tabContainer == null) {
            tabContainer = new LinearLayout(context);
            tabContainer.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
            tabContainer.setOrientation(LinearLayout.HORIZONTAL);
            addView(tabContainer, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        }
    }

    private void init(Context context) {
        addContainer(context);
        mIndicatorPaint = new Paint();
        mIndicatorPaint.setColor(mSelectColor);
        mIndicatorPaint.setAntiAlias(true);
        mOnTabClickListener = new OnClickListenerTab();

        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display defaultDisplay = wm.getDefaultDisplay();
        DisplayMetrics outMetrics = new DisplayMetrics();
        defaultDisplay.getMetrics(outMetrics);
        mIndicatorHeight = (int) (2 * outMetrics.density);
        mIndicatorWidth = (int) (30 * outMetrics.density);
        mDensity = outMetrics.density;
    }

    private Integer evaluate(float fraction, Object startValue, Integer endValue) {
        int startInt = (Integer) startValue;
        int startA = (startInt >> 24) & 0xff;
        int startR = (startInt >> 16) & 0xff;
        int startG = (startInt >> 8) & 0xff;
        int startB = startInt & 0xff;
        int endInt = endValue;
        int endA = (endInt >> 24) & 0xff;
        int endR = (endInt >> 16) & 0xff;
        int endG = (endInt >> 8) & 0xff;
        int endB = endInt & 0xff;
        return (startA + (int) (fraction * (endA - startA))) << 24 | (startR + (int) (fraction * (endR - startR))) << 16 | (startG + (int) (fraction * (endG - startG))) << 8
                | (startB + (int) (fraction * (endB - startB)));
    }

    class OnClickListenerTab implements OnClickListener {
        @Override
        public void onClick(View v) {
            int position = getPositionForView(v);
            try {
                if ((position == mCurrentPosition)) {
                    return;
                }
                onTabSelect(position);
                mCurrentPosition = position;
                mCurScrollPosition = position;
                LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) v.getLayoutParams();
                float screenOffset = (getWidth() - v.getWidth()) / 2f;
                int desScrollX = (int) (v.getLeft() - params.leftMargin - screenOffset);
                smoothScrollTo(desScrollX, 0);
                invalidate();
            } catch (Exception e) {

            }
        }
    }


}
